
    /********************************************************/
    /*                                                      */
    /*                                                      */
    /*         Copyright (C), 1993  SEIKO EPSON Corp.       */
    /*         ALL RIGHTS RESERVED                          */
    /*                                                      */
    /*                                                      */
    /*  file name : bsearch.c                               */
    /*                                                      */
    /*  Revision history                                    */
    /*      93/12/17    first release       S.Akaiwa        */
    /*      97/2/20	modified	    T.Katahira	    */
    /*			change function declaration	    */
    /*					to the ANSI style   */
    /*                                                      */
    /********************************************************/

#ifdef      UNIX
#include    "stdlib.h"
#else
#include    <stdlib.h>
#endif

void *
bsearch(const void * vpKey, const void * vpBase, 
		size_t tdCnt, size_t tdSiz, fn_t * fnCmp)

    /********************************************************/
    /*                                                      */
    /*  The bsearch function searchs data pointed to by     */
    /*  vpKey out of array pointed to by vpBase.            */
    /*  The number of element in the array is specified by  */
    /*  tdCnt, and size of a element is specified by tdSiz. */
    /*  The comparison function pointer to by fnCmp is      */
    /*  called with 2 arguments that point to vpKey and     */
    /*  an array element, in that order. This function must */
    /*  return an integer less than , equal to , or greater */
    /*  than 0 if the key object is considered,             */
    /*  respectively, to be less than, to much, or to be    */
    /*  greater than the array element.                     */
    /*  The bsearch function returns pointer to matching    */
    /*  element into the array.                             */
    /*  If no match is found, this function returns NULL    */
    /*  pointer.                                            */
    /*                                                      */
    /*      RETURN  NULL    ... No match                    */
    /*              Others  ... Pointer to matching element */
    /*                                                      */
    /********************************************************/

    /* void    * vpKey   ;            pointer to search data */
    /* void    * vpBase  ;                  pointer to array */
    /* size_t    tdSiz   ;                 size of a element */
    /* size_t    tdCnt   ;                 number of element */
    /* fn_t    * fnCmp   ;    pointer to comparison function */
    {

     char   * vpTmpBase;         /* pointer to top of array */
     char   * vpMidPtr;       /* pointer to middle of array */
     size_t   tdTmpCnt;                    /* element count */
     int      iRetVal;                      /* return value */

     vpTmpBase = vpBase;         /* save array base pointer */
     tdTmpCnt = tdCnt;                /* save element count */

     while(tdTmpCnt > 0){ /* compare data during data exist */
                                /* calculate middle pointer */
        vpMidPtr = vpTmpBase + (tdTmpCnt / 2 * tdSiz);
        if((iRetVal = fnCmp(vpKey, vpMidPtr)) == 0){
                                  
           return (void *)vpMidPtr;   /* return matched ptr */
        }
        else {
           if(iRetVal > 0){          /* data exist in upper */
              vpTmpBase = vpMidPtr + tdSiz;  /* modify base */
              tdTmpCnt --;
           }
           tdTmpCnt = tdTmpCnt / 2;  /* halve element count */
        }
     }

     return (void *)NULL;          /* data does not matched */
    }

